home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / sound / sendmors.1
Text File  |  1988-12-06  |  25KB  |  721 lines

  1. Path: xanth!mcnc!rutgers!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i093:  sendmorse - morse code generator
  5. Message-ID: <10514@swan.ulowell.edu>
  6. Date: 6 Dec 88 23:00:28 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 710
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: joe@dayton.dhdsc.mn.org (Joseph P. Larson)
  12. Posting-number: Volume 2, Issue 93
  13. Archive-name: sound/sendmorse.1
  14.  
  15. This program converts text files to morse code (out the audio port).
  16.  
  17. [uuencoded binary included here; it's small.  ..Bob]
  18.  
  19. #    This is a shell archive.
  20. #    Remove everything above and including the cut line.
  21. #    Then run the rest of the file through sh.
  22. #----cut here-----cut here-----cut here-----cut here----#
  23. #!/bin/sh
  24. # shar:    Shell Archiver
  25. #    Run the following text with /bin/sh to create:
  26. #    readme
  27. #    Makefile
  28. #    SendMorse.c
  29. #    SendMorse.h
  30. #    SendMorse.uu
  31. # This archive created: Tue Dec  6 17:56:12 1988
  32. cat << \SHAR_EOF > readme
  33.  
  34. SendMorse is a little program I kinda "whipped up" for 2 purposes:
  35.  
  36.     1. Learn more about the audio.device (translate: learn something,
  37.         *anything* about the audio.device)
  38.     2. Practice my very ailing Morse code.
  39.  
  40. Thus, here it is in its glorious entirety.  (Gag).  Note that it's
  41. very heavily based on Rob Peck's "audio.c" from Chapter 8 of his book.
  42. Very heavily.....
  43.  
  44. For those who think I have a weird Makefile -- not ALL of us can have
  45. hard disks.  This make works very quickly as it throws everything into
  46. ram:.  Note the odd location of c.lib.  I have c32.lib on my SYS1 disk,
  47. so I had to put c.lib on my work disk....
  48.  
  49.  
  50. To use it: say "SendMorse [-sendrate] <filelist>".  It will send the
  51. files in the file list at the given word rate.  Default is 5.
  52.  
  53. Joe Larson (that's still me -- joe@dayton)
  54. November 12, 1988
  55. Golden Valley, Mn.
  56.  
  57. -------------------Little Notes Follow Hereafter----------------------
  58. A few little notes concerning timings for those who want to fiddle...  
  59.  
  60. There are a few items that may be worth fiddling with.
  61.  
  62.     1. The wave form.  I used a short sine wave sample that took me
  63.         about 20 seconds on my calculator.  However, it clicks a little
  64.         at the start of each dit or dah.  I don't know why.  I hope
  65.         someone tells me.....
  66.  
  67.     2. The MORSE_PERIOD value.  This defines the period of the sample.
  68.         (See the discussion on the audio.device for a definition of
  69.         this.)  Higher values mean lower frequency.
  70.  
  71.     3. The calculations for ditlength, ditcycles and dahcycles.  I
  72.         decided that I didn't want longer dits and dahs at slower speeds
  73.         but would just add more spacing between letters and words.  Thus,
  74.         ditcycles is a constant and dahcycles is 3*ditcycles.  You may
  75.         want to fiddle with these, but I think it works out well.
  76.  
  77.         Ditlength, though, was originally how long a dit was supposed
  78.         to be.  And I was using a ditlength pause between dits and
  79.         dahs and 3*ditlength between letters.  I have a constant defined
  80.         somewhere that is the number of ditlengths between words (currently
  81.         6).  This item is in 20 millisecond increments, as that's what
  82.         the Delay() function *seems* to use.
  83.  
  84.         Because of all this, the sendrate appears to be maybe a little
  85.         higher than you ask for.  That is, the default of 5 WPM on a 20
  86.         character sample SHOULD take about 48 seconds but seems to be a
  87.         little closer to 35 or 40.  You can add a little fudge factor
  88.         if you like -- I'm not too concerned about it.....
  89.  
  90.     4. Channel allocation.  I only use one channel.  I should probably
  91.         have used Rob's "GetAnyStereoPair" rather than just grabbing
  92.         a single channel, but that's the way it goes.
  93. SHAR_EOF
  94. cat << \SHAR_EOF > Makefile
  95.  
  96. SendMorse: ram:SendMorse
  97.     copy ram:SendMorse SendMorse
  98.  
  99. ram:SendMorse.o: SendMorse.c SendMorse.h
  100.     make ram:SendMorse.c
  101.     make ram:SendMorse.syms
  102.     cc +Iram:SendMorse.syms ram:SendMorse.c
  103.     copy ram:SendMorse.o SendMorse.o
  104.  
  105. ram:SendMorse.c: SendMorse.c
  106.     copy SendMorse.c ram:
  107.  
  108. ram:SendMorse.syms: SendMorse.h
  109.     cc +Hram:SendMorse.syms SendMorse.h
  110.     copy ram:SendMorse.syms SendMorse.syms
  111.  
  112. ram:SendMorse: ram:SendMorse.o
  113.     make ram:c.lib
  114.     ln -o ram:SendMorse ram:SendMorse.o -lram:c
  115.  
  116. ram:c.lib: df1:lib/c.lib
  117.     copy df1:lib/c.lib ram:
  118.  
  119. SHAR_EOF
  120. cat << \SHAR_EOF > SendMorse.c
  121. #include "SendMorse.h"
  122.  
  123. #define        MORSE_C1000        3579
  124. #define        MORSE_PERIOD    500
  125. #define        MORSE_LENGTH    6
  126. #define        MORSE_SPACE        6            /* # of dits between words */
  127.  
  128. BYTE sinewave[8] = {0, 90, 127, 90, 0, -90, -127, -90};
  129.  
  130. struct Device    *auDevice=0;
  131. struct IOAudio    *audioIOB;
  132. struct IOAudio    *aulockIOB;
  133. struct IOAudio    *aufreeIOB;
  134. BYTE            *chipaudio = 0;
  135.  
  136. struct MsgPort *auReplyPort, *auLockPort;
  137.  
  138. extern UBYTE            *AllocMem();
  139. extern struct MsgPort    *CreatePort();
  140.  
  141. struct IOAudio            *CreateAudioIO();
  142. UBYTE                    GetAnyChannel();
  143. void                    FreeAudioIO();
  144.  
  145. #define isalpha(c)    (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
  146. #define isdigit(c)    ((c >= '0') && (c <= '9'))
  147.  
  148. long    sendrate = 5, ditcycles, dahcycles, ditlength;
  149.  
  150. main(argc,argv)
  151. int argc;
  152. char **argv;
  153. {
  154.     short i;
  155.  
  156.     GetSoundStuff();
  157.     for (i = 1; i < argc; i++)
  158.     {
  159.         if (*argv[i] == '-')
  160.         {
  161.             sendrate = atoi(argv[i]+1);
  162.             if (sendrate <= 0)
  163.                 finishup("usage: code [-sendrate] <filelist>");
  164.         }
  165.         else
  166.             Work(argv[i]);
  167.     }
  168.  
  169.     FreeAChannel(aufreeIOB);
  170.     finishup("all done");
  171. }
  172.  
  173.  
  174. GetSoundStuff()
  175. {
  176.     int        i;
  177.     UBYTE    chan;
  178.  
  179.     audioIOB  = CreateAudioIO();
  180.     aulockIOB = CreateAudioIO();
  181.     aufreeIOB = CreateAudioIO();
  182.  
  183.     if(audioIOB == 0 || aufreeIOB == 0 | aulockIOB == 0)
  184.         finishup("out of memory!");
  185.  
  186.     if ((chipaudio = (BYTE *)AllocMem(8L, MEMF_CHIP)) == 0)
  187.         finishup("out of memory!");
  188.     for (i = 0; i < 8; i++)
  189.         chipaudio[i] = sinewave[i];
  190.  
  191.     if (OpenDevice("audio.device",0L,audioIOB,0L))
  192.         finishup ("audio device won't open!");
  193.  
  194. /* Get the device address for later use */
  195.     auDevice = audioIOB->ioa_Request.io_Device;
  196.  
  197. /* Create ports for replies from the device */
  198.     auReplyPort = CreatePort(0L,0L);
  199.     auLockPort  = CreatePort(0L,0L);
  200.  
  201.     if(auReplyPort == 0 || auLockPort == 0) 
  202.         finishup("cannot create a port!");
  203.  
  204. /*
  205.  * initialize port addresses and device fields 
  206.  * for all audio request blocks 
  207.  */
  208.     audioIOB->ioa_Request.io_Device = auDevice;
  209.     aulockIOB->ioa_Request.io_Device = auDevice;
  210.  
  211.     audioIOB->ioa_Request.io_Message.mn_ReplyPort  = auReplyPort;
  212.     aulockIOB->ioa_Request.io_Message.mn_ReplyPort  = auLockPort;
  213.  
  214.     chan = GetAnyChannel(audioIOB);
  215.  
  216.     /* Make the allocation keys match */
  217.     aulockIOB->ioa_AllocKey = audioIOB->ioa_AllocKey;
  218.  
  219.     /* Make the unit numbers match */
  220.     aulockIOB->ioa_Request.io_Unit = audioIOB->ioa_Request.io_Unit;
  221.  
  222.     LockAChannel(aulockIOB,chan);
  223.  
  224. /*
  225.  * If checkio returns true, it means the request has
  226.  * been returned.  This means the channel has been
  227.  * stolen.
  228.  */
  229.  
  230.     if(CheckIO(aulockIOB))
  231.         finishup("A channel was stolen!");
  232.  
  233. /*
  234.  * now assuming nothing stolen, setup and request
  235.  * an output from that channel.
  236.  */
  237.     audioIOB->ioa_Data   = (UBYTE *)chipaudio;
  238.     audioIOB->ioa_Length = 8/2;         /* 4 WORDS in table */
  239.     audioIOB->ioa_Period = MORSE_PERIOD;    /* from table */
  240.     audioIOB->ioa_Volume = 64;            /* maximum */
  241.     audioIOB->ioa_Cycles = 1000;        /* # of times */
  242.  
  243.     audioIOB->ioa_Request.io_Command = CMD_WRITE;
  244.     audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
  245.  
  246.     /* copy the audio block for freeing channels later */
  247.     *aufreeIOB = *audioIOB;
  248.  
  249. }
  250.  
  251.  
  252. finishup(string)
  253. char *string;
  254. {
  255.     if(auDevice) CloseDevice(audioIOB);
  256.     if(chipaudio) FreeMem(chipaudio,8L);
  257.     if(audioIOB) FreeAudioIO(audioIOB);
  258.     if(aulockIOB) FreeAudioIO(aulockIOB);
  259.     if(auReplyPort) DeletePort(auReplyPort);
  260.     if(auLockPort)  DeletePort(auLockPort);
  261.  
  262.     printf("%ls\n",string);
  263.     exit(0);
  264. }
  265.  
  266.  
  267.  
  268. /* newaudioblock.c */
  269.  
  270. struct IOAudio *
  271. CreateAudioIO()
  272. {
  273.     struct IOAudio *iob;
  274.  
  275.     iob = (struct IOAudio *) AllocMem((long)sizeof(struct IOAudio),
  276.             MEMF_CHIP | MEMF_CLEAR);
  277.  
  278.     return(iob);    /* returns 0 if out of memory */
  279. }
  280.  
  281. void    
  282. FreeAudioIO(iob)
  283. struct IOAudio *iob;
  284. {
  285.     FreeMem(iob, (long)sizeof(struct IOAudio));
  286. }
  287.  
  288.  
  289.  
  290. /* lockachannel.c */
  291.  
  292. LockAChannel(lockiob,channel)
  293. struct IOAudio *lockiob;
  294. UBYTE channel;
  295. {
  296.     /* tell it which channel to lock */
  297.  
  298. /*    lockiob->ioa_Request.io_Unit = (struct Unit *)channel;    */
  299.  
  300.     lockiob->ioa_Request.io_Command = ADCMD_LOCK;
  301.     lockiob->ioa_Request.io_Flags = 0;
  302.  
  303.     /* Send this command.  It does not return to 
  304.      * the reply port unless and until either this
  305.      * task frees the channel or another channel of
  306.      * higher precedence steals it.  Appropriate
  307.      * to keep two reply ports, perhaps... one for
  308.      * standard I/O replies, other for channel steal
  309.      * requests. 
  310.      */
  311.     BeginIO(lockiob);
  312. }
  313.  
  314. FreeAChannel(iob)
  315. struct IOAudio *iob;
  316. {
  317.     /* allocation key and unit number must already be valid */
  318.     iob->ioa_Request.io_Command = ADCMD_FREE;
  319.     iob->ioa_Request.io_Flags = IOF_QUICK;
  320.     BeginIO(iob);
  321.     WaitIO(iob);
  322. }
  323.  
  324. /* getaudio.c */
  325.  
  326.  
  327. UBYTE
  328. GetAnyChannel(iob)
  329. struct IOAudio *iob;
  330. {
  331.     UBYTE anychan[4];
  332.     UBYTE mychan;
  333.     int error;
  334.  
  335.     anychan[0] = 1;
  336.     anychan[1] = 2;
  337.     anychan[2] = 4;
  338.     anychan[3] = 8;
  339.  
  340.     iob->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
  341.     iob->ioa_Request.io_Command = ADCMD_ALLOCATE;
  342.     iob->ioa_Data = (UBYTE *)anychan;
  343.     iob->ioa_Length = 4;
  344.     iob->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
  345.     BeginIO(iob); 
  346.     error = WaitIO(iob);  /* returns nonzero if error */
  347.  
  348.     if(!(iob->ioa_Request.io_Flags & IOF_QUICK))
  349.         GetMsg(iob->ioa_Request.io_Message.mn_ReplyPort);
  350.     if(error)
  351.         return(0);
  352.     mychan = ((ULONG)(iob->ioa_Request.io_Unit)) & 0xFF;
  353.     return(mychan);
  354. }
  355.  
  356.  
  357.  
  358.  
  359. #define        MAX_LETTERS        47
  360. char *letters[MAX_LETTERS] =
  361. {
  362.     ".-",                /* A */
  363.     "-...",                /* B */
  364.     "-.-.",                /* C */
  365.     "-..",                /* D */
  366.     ".",                /* E */
  367.     "..-.",                /* F */
  368.     "--.",                /* G */
  369.     "....",                /* H */
  370.     "..",                /* I */
  371.     ".---",                /* J */
  372.     "-.-",                /* K */
  373.     ".-..",                /* L */
  374.     "--",                /* M */
  375.     "-.",                /* N */
  376.     "---",                /* O */
  377.     ".--.",                /* P */
  378.     "--.-",                /* Q */
  379.     ".-.",                /* R */
  380.     "...",                /* S */
  381.     "-",                /* T */
  382.     "..-",                /* U */
  383.     "...-",                /* V */
  384.     ".--",                /* W */
  385.     "-..-",                /* X */
  386.     "-.--",                /* Y */
  387.     "--..",                /* Z */
  388.     "-----",                /* 0 */
  389.     ".----",                /* 1 */
  390.     "..---",                /* 2 */
  391.     "...--",                /* 3 */
  392.     "....-",                /* 4 */
  393.     ".....",                /* 5 */
  394.     "-....",                /* 6 */
  395.     "--...",                /* 7 */
  396.     "---..",                /* 8 */
  397.     "----.",                /* 9 */
  398.     "--..--",                /* , */
  399.     ".-.-.-",                /* . */
  400.     "..--..",                /* ? */
  401.     "-.-.-.",                /* ; */
  402.     "---...",                /* : */
  403.     "-..-.",                /* / */
  404.     "-....-",                /* - */
  405.     ".----.",                /* ' */
  406.     "-.--.-",                /* () */
  407.     "..--.-",                /* _ */
  408. };
  409.  
  410.  
  411.  
  412. Work(fname)
  413. char *fname;
  414. /*
  415.  * Get strings and send them to the audio port.
  416.  *
  417.  * Dlen: 1000 millis/sec * 1/8 chars/dit * 1/25 min/chars * 1/60 secs/min
  418.  */
  419. {
  420.     char    *cptr, line[132];
  421.     FILE    *file;
  422.  
  423.     if ((file = fopen(fname, "r")) == NULL)
  424.         finishup("can't open a file");
  425.     ditlength = 75 / sendrate;        /* In 20 milliseconds */
  426.      ditcycles = 12 * (MORSE_C1000 / MORSE_PERIOD);
  427.     dahcycles = ditcycles * 3;
  428.     while (fgets(line, 132, file))
  429.     {
  430.         for (cptr = line; *cptr && (*cptr != '\n'); cptr++)
  431.         {
  432.             SendLetter(*cptr);
  433.             PauseDit(3);
  434.         }
  435.     }
  436.     fclose(file);
  437. }
  438.  
  439.  
  440. SendLetter(c)
  441. char c;
  442. /*
  443.  * Send character c.
  444.  */
  445. {
  446.     char    *cptr, *temp = ",.?;:;/-,{}_", *findchar();
  447.     short    i;
  448.  
  449.     if (c == ' ')
  450.     {
  451.         PauseDit(MORSE_SPACE);
  452.         return;
  453.     }
  454.     if (isalpha(c))
  455.         c = tolower(c) - 'a';
  456.     else if (isdigit(c))
  457.         c = c - 'a' + 26;
  458.     else
  459.     {
  460.         cptr = findchar(temp, c);
  461.         c = 37 + cptr - temp;
  462.     }
  463.     cptr = letters[c];
  464.     i = 0;
  465.     for ( ; *cptr != 0; cptr++, i++)
  466.     {
  467.         if (i)
  468.             PauseDit(1);
  469.         /*
  470.          * We'll send each dit or dah.  We know it's done when WaitIO
  471.          *        returns.  I think.
  472.          */
  473.         if (*cptr == '.')
  474.             audioIOB->ioa_Cycles = ditcycles;
  475.         else
  476.             audioIOB->ioa_Cycles = dahcycles;
  477.         BeginIO(audioIOB);
  478.         WaitIO(audioIOB);
  479.     }
  480. }
  481.  
  482. char *findchar(s,c)
  483. char *s,c;
  484. {
  485.     for ( ; *s; s++)
  486.         if (*s == c)
  487.             return(s);
  488.     return(NULL);
  489. }
  490.  
  491.  
  492. PauseDit(ditcount)
  493. short ditcount;
  494. /*
  495.  * Pause for ditcount dit periods.
  496.  *
  497.  *        Do this by setting the timer and waiting for it.
  498.  */
  499. {
  500.     Delay((long)(ditcount * ditlength));
  501. }
  502. SHAR_EOF
  503. cat << \SHAR_EOF > SendMorse.h
  504. #include "stdio.h"
  505. #include "exec/types.h"
  506. #include "exec/memory.h"
  507. #include "devices/audio.h"
  508. SHAR_EOF
  509. cat << \SHAR_EOF > SendMorse.uu
  510.  
  511. begin 644 SendMorse
  512. M```#\P`````````#``````````(```>K````[@````$```/I```'JT[Z"G9.0
  513. M5?_^3KH`NCM\``'__F!B,"W__DC`Y8`@;0`*(G`(``P1`"UF,C`M__Y(P.6`L
  514. M(&T`"B)P"`!2B2\)3KH'>%A/2,`I0(`22JR`$FX*2'H`1DZZ`J!83V`6,"W_@
  515. M_DC`Y8`@;0`*+S`(`$ZZ!2Q83U)M__XP+?_^L&T`"&V4+RR#GDZZ`TY83TAZ#
  516. M`"].N@)F6$].74YU=7-A9V4Z(&-O9&4@6RUS96YD<F%T95T@/&9I;&5L:7-T1
  517. M/@!A;&P@9&]N90!.5?_\3KH"L"E`@Y9.N@*H*4"#FDZZ`J`I0(.>2JR#EF<<5
  518. M2JR#GF8$<`%@`G``2JR#FF8$<@%@`G(`@$%G"DAZ`8).N@'N6$](>``"2'@`?
  519. M"$ZZ')Y03RE`@`YF"DAZ`7-.N@'06$]";?_^,"W__D'L@`(R+?_^(FR`#A.PV
  520. M```0`%)M__X,;0`(__YMWD*G+RR#ED*G2'H!2DZZ',)/[P`02D!G"DAZ`4=.O
  521. MN@&(6$\@;(.6*6@`%(`*0J="ITZZ&TA03RE`@Z)"IT*G3KH;.E!/*4"#IDJL^
  522. M@Z)G!DJL@Z9F"DAZ`21.N@%,6$\@;(.6(6R`"@`4(&R#FB%L@`H`%"!L@Y8AN
  523. M;(.B``X@;(.:(6R#I@`.+RR#EDZZ`BA83QM`__T@;(.6(FR#FC-H`"``("!LG
  524. M@Y8B;(.:(V@`&``8<``0+?_]/P`O+(.:3KH!HEQ/+RR#FDZZ&HI83TI`9PI(#
  525. M>@"^3KH`T%A/(&R#EB%L@`X`(B!L@Y8A?`````0`)B!L@Y8Q?`'T`"H@;(.6;
  526. M,7P`0``L(&R#EC%\`^@`+B!L@Y8Q?``#`!P@;(.6$7P`$``>(&R#GB)L@Y9P9
  527. M$"#94<C__$Y=3G5O=70@;V8@;65M;W)Y(0!O=70@;V8@;65M;W)Y(0!A=61I\
  528. M;RYD979I8V4`875D:6\@9&5V:6-E('=O;B=T(&]P96XA`&-A;FYO="!C<F5AO
  529. M=&4@82!P;W)T(0!!(&-H86YN96P@=V%S('-T;VQE;B$`3E4``$JL@`IG"B\L*
  530. M@Y9.NAFH6$]*K(`.9PY(>``(+RR`#DZZ&L103TJL@Y9G""\L@Y9A<%A/2JR#;
  531. MFF<(+RR#FF%B6$]*K(.B9PHO+(.B3KH:$%A/2JR#IF<*+RR#IDZZ&@!83R\M)
  532. M``A(>@`43KH-NE!/0F=.NA<25$].74YU)6QS"@``3E7__$AY``$``DAX`$1.Y
  533. MNAHJ4$\K0/_\("W__$Y=3G5.50``2'@`1"\M``A.NAHV4$].74YU3E4``"!M9
  534. M``@Q?``-`!P@;0`(0B@`'B\M``A.NAC*6$].74YU3E4``"!M``@Q?``)`!P@(
  535. M;0`($7P``0`>+RT`"$ZZ&*183R\M``A.NAIP6$].74YU3E7_^!M\``'__!M\_
  536. M``+__1M\``3__AM\``C__R!M``@1?``4``D@;0`(,7P`(``<0>W__")M``@C3
  537. M2``B(&T`""%\````!``F(&T`"!%\`$$`'B\M``A.NA@Z6$\O+0`(3KH:!EA/?
  538. M.T#_^"!M``@(*````!YF#B!M``@O*``.3KH9>EA/2FW_^&<&<`!.74YU(&T`+
  539. M""`H`!C`O````/\;0/_[$"W_^V#D+BT`+2XN+@`M+BTN`"TN+@`N`"XN+2X`I
  540. M+2TN`"XN+BX`+BX`+BTM+0`M+BT`+BTN+@`M+0`M+@`M+2T`+BTM+@`M+2XMW
  541. M`"XM+@`N+BX`+0`N+BT`+BXN+0`N+2T`+2XN+0`M+BTM`"TM+BX`+2TM+2T`*
  542. M+BTM+2T`+BXM+2T`+BXN+2T`+BXN+BT`+BXN+BX`+2XN+BX`+2TN+BX`+2TM$
  543. M+BX`+2TM+2X`+2TN+BTM`"XM+BTN+0`N+BTM+BX`+2XM+BTN`"TM+2XN+@`M`
  544. M+BXM+@`M+BXN+BT`+BTM+2TN`"TN+2TN+0`N+BTM+BT``$Y5_W1(>@"@+RT`.
  545. M"$ZZ!#103RM`_W1F"DAZ`(Y.NOT^6$\B+(`2<$M.N@\>*4"#LBE\````5(.J#
  546. M<@,@+(.J3KH*;"E`@ZXO+?]T/SP`A$AM_WA.N@)L3^\`"DI`9SI![?]X*TC_`
  547. M_&`<(&W__!`02(`_`&%&5$\_/``#3KH!A%1/4JW__"!M__Q*$&<*(FW__`P13
  548. M``IFTF"N+RW_=$ZZ$"!83TY=3G5R`&-A;B=T(&]P96X@82!F:6QE`$Y5__9!7
  549. M^@$(*TC_^`PM`"``"68./SP`!DZZ`2Q43TY=3G4,+0!A``EM"`PM`'H`"6\0=
  550. M#"T`00`);2`,+0!:``EN&!`M``E(@#\`3KH!HE1/D'P`81M```E@0@PM`#``I
  551. M"6T0#"T`.0`);@@$+0!'``E@*A`M``E(@#\`+RW_^$ZZ`)Q<3RM`__P@;?_\?
  552. MT?P````ED>W_^#`(&T``"1`M``E(@$C`Y8!![(`6*W`(`/_\0FW_]F!,2FW_E
  553. M]F<*/SP``4ZZ`(143R!M__P,$``N9@P@;(.6,6R#K``N8`H@;(.6,6R#L``N"
  554. M+RR#EDZZ%5983R\L@Y9.NA<B6$]2K?_\4FW_]B!M__Q*$&:L8`#_$BPN/SLZ+
  555. M.R\M+'M]7P``3E4``&`8(&T`"!`0L"T`#68(("T`"$Y=3G52K0`((&T`"$H0[
  556. M9N!P`&#L3E4``#`M``A(P"(L@[).N@B<+P!.NA1`6$].74YU3E4``$CG#"`D#
  557. M;0`(#!(`(&<&#!(`"68$4HI@\'H`#!(`+68&>@%2BF`(#!(`*V8"4HIX`&`6(
  558. M($I2BA`02(`R!,+\``K003@`F'P`,!`22(!20$'L@1H(,``"``!FV$I%9P8PA
  559. M!$1`8`(P!$S?!#!.74YU<``0+P`%L#P`8&,*L#P`>F($D#P`($YU<``0+P`%'
  560. ML#P`0&,*L#P`6F($T#P`($YU3E4``$CG""`D;0`(4VT`#$IM``QO("\M``Y.=
  561. MN@`X6$\X`+!\__]G#B!*4HH0A+A\``IG`F#60A*X?/__9A"U[0`(9@IP`$S?8
  562. M!!!.74YU("T`"&#R3E4``$CG""`D;0`(+PI.N@`R6$\X`+!\__]G(C`$2,!@=
  563. M%%.2".H``P`,</],WP003EU.=6#62H!G^EF`9^0P!&#J3E4``"\*)&T`""!2`
  564. ML>H`!&4,+PIA%EA/)%].74YU(%)2DA`02(#`?`#_8.Q.50``2.<(,"1M``@00
  565. M*@`,P#P`&&<*</],WPP03EU.=0BJ``(`#$JJ``AF""\*3KH.K%A/$"H`#$B`Y
  566. M"```!V<P0>R!G"9($"L`#$B`P'P`A+!\`(1F##\\__\O"TZZ#61<3]?\````Y
  567. M%D'L@U2WR&76/RH`$"\J``@0*@`-2(`_`$ZZ!;Q03S@`2D!N%$I$9@1P"&`"Z
  568. M<!"!*@`,</]@`/]Z,`1(P"2J``C0J@`()4``!"!24I(0$$B`P'P`_V``_UI.\
  569. M50``+PI.N@W<)$!*@&8(<``D7TY=3G4O"B\M``PO+0`(809/[P`,8.A.50``=
  570. M2.<(("\M`!!.N@Q$6$]![(#2)$A*$F80.7P`!8-:<`!,WP003EU.=2\M``PO*
  571. M"DZZ!<Q03TI`9P1<BF#8/RH`!"\M``A.N@.^7$\X`+!\__]F!'``8,H@;0`0=
  572. M$40`#2!M`!`1?``!``P@+0`08+)A<$/L@U9%[(-6M<EF#C(\`!AK"'0`(L)1_
  573. MR?_\*4^#7"QX``0I3H-@2.>`@`@N``0!*6<02_H`"$ZN_^)@!D*G\U].<T/ZP
  574. M`"!.KOYH*4"#9&8,+CP``X`'3J[_E&`$3KH`&E!/3G5D;W,N;&EB<F%R>0!)A
  575. M^0``?_Y.=4Y5```O"DAY``$``#`L@U3!_``&+P!.NA*N4$\I0(-H9A1"ITAY;
  576. M``$``$ZZ$6!03RYL@UQ.=2!L@VA":``$(&R#:#%\``$`$")L@V@S?``!``H@"
  577. M;(-<("R#7)"H``10@"E`@VP@;(-L(+Q-04Y80J=.NA)F6$\D0$JJ`*QG+B\MJ
  578. M``PO+0`(+PI.N@"R3^\`##E\``&#<"!L@V@`:(````0@;(-H`&B````*8$1(.
  579. M:@!<3KH2U%A/2&H`7$ZZ$E183RE`@W(@;(-R2J@`)&<0(&R#<B)H`"0O$4ZZA
  580. M$!A83R\L@W(O"DZZ!))03REL@W*#=DZZ$"0@;(-H((!.NA!2(&R#:"%```9G:
  581. M%DAX`^U(>@`L3KH0+E!/(&R#:"%```PO+(-V/RR#>DZZ\^I<3T)G3KH.7%1/'
  582. M)%].74YU*@!.50``2.<,,"1M`!`@;0`(("@`K.6`*``@1"`H`!#E@"9`$!-(2
  583. M@$C`T*T`#%2`.4"#?$*G,"R#?$C`+P!.NA%,4$\I0(-^9@A,WPPP3EU.=1`3L
  584. M2(`_`"!+4H@O""\L@WY.N@%$3^\`"DAZ`3H0$TB`2,#0K(-^+P!.N@..4$\_'
  585. M+0`.+PHO+(-^3KH#*D_O``I";(-Z)FR#?B1+$!-(@#H`L'P`(&<8NGP`"6<2B
  586. MNGP`#&<,NGP`#6<&NGP`"F8$4HM@V`P3`"!M>@P3`")F+E*+($M2BQ`02(`ZF
  587. M`&<>($I2BA"%NGP`(F80#!,`(F8$4HM@!D(J__]@`F#68#@@2U*+$!!(@#H`@
  588. M9R:Z?``@9R"Z?``)9QJZ?``,9Q2Z?``-9PZZ?``*9P@@2E**$(5@SB!*4HI"?
  589. M$$I%9@)3BU)L@WI@`/]:0A)"IS`L@WI20$C`Y8`O`$ZZ$#903RE`@W9F"$)L(
  590. M@WI@`/[D>@`F;(-^8!XP!4C`Y8`@;(-V(8L(`"\+3KH'W%A/4D!(P-?`4D6ZS
  591. M;(-Z;=PP!4C`Y8`@;(-V0K`(`&``_J8@`$SO`P``!"`(,B\`#&`"$-E7R?_\T
  592. M9P9206`"0AA1R?_\3G5.50``/RT`##\\`P$O+0`(80903TY=3G5.50``2.</G
  593. M,"1M``A.N@P&)FR#:'@`8`XP!,'\``9*LP@`9PY21+AL@U1M['H&8```R@@M`
  594. M``$`#&<R2'C__R\*3KH-U%!/+`!G(B\&3KH."%A/+PI.N@V86$]*@&8.3KH-T
  595. MHCH`L'P`S68``)!(>`/M+PI.N@VP4$\L`$J&9F0(+0````QF!'H!8'!(>`/N%
  596. M+PI.N@V24$\L`&8(3KH-9CH`8%A(>``A2'H`EDZZ#WQ03RX`9PHO!TZZ#?A8K
  597. M3V`B2'@``4AZ`(8O!DZZ#9A/[P`,2'C__T*G+P9.N@UN3^\`#&`F,"T`#,!\:
  598. M!0"P?`4`9A@O!DZZ#-983WH$.46#6G#_3-\,\$Y=3G4P!,'\``8GA@@`,`3!X
  599. M_``&($#1RS%M``P`!`@M``,`#&<02'@``4*G+P9.N@T43^\`##`$8,)D;W,N#
  600. M;&EB<F%R>0```$Y5``!(YPP@."T`"$ZZ"KHP!,'\``8D0-7L@VA*1&T*N&R#?
  601. M5&P$2I)F$#E\``*#6G#_3-\$,$Y=3G4P*@`$P'P``[!\``%F"CE\``6#6G#_F
  602. M8.!P`#`M``XO`"\M``HO$DZZ#(Q/[P`,*@"PO/____]F#$ZZ#$(Y0(-:</]@:
  603. MM"`%8+`P/'__8`0P+P`,(&\`!$H89OQ32")O``A30!#95\C__&<"0A`@+P`$1
  604. M3G4P/'__8`0P+P`,4T!K%"!O``0B;P`(L0EF#%-(2AA7R/_V<`!.=6,$<`%.0
  605. M=7#_3G4@;P`$(`@B;P`($-EF_$YU2.=P`#0!Q,`F`4A#QL!(0T)#U(-(0,#!)
  606. M2$!"0-""3-\`#DYU3E4``$CG#C`D;0`(0J=(>@".3KH-N%!/*4"#MF8(3-\,M
  607. M<$Y=3G4@;0`,(F@`)"\I``1.N@X`6$\H`&=22'H`;2!$+R@`-DZZ#=)03R9`K
  608. M2H!G-$AX`^TO"TZZ"VY03RP`9R0@!N6`*@`@125H``@`I"5&`)Q(>`/M2'H`R
  609. M.$ZZ"TI03R5``*`O!$ZZ#9Y83R\L@[9.N@N\6$]"K(.V8(!I8V]N+FQI8G)AX
  610. M<GD`5TE.1$]7`"H`3E4``$AM``PO+0`(2'H$<$ZZ`)A/[P`,3EU.=4Y5``!(N
  611. MYP@@)&T`#@QM``0`$F8((&T`""@08!Q*;0`,;PP@;0`(<``P$"@`8`H@;0`(>
  612. M,!!(P"@`0FT`$DIM``QL$$1M``Q*A&P(1(0[?``!`!(R+0`,2,$@!$ZZ`XY!S
  613. M[($(4XH4L```,BT`#$C!(`1.N@.$*`!FVDIM`!)G!E.*%+P`+2`*3-\$$$Y=)
  614. M3G5.5?\B2.<(,"1M``@F;0`,0FW_^BMM`!#__"!+4HL0$$B`.`!G``+LN'P`B
  615. M)68``LI"+?\P.WP``?_X.WP`(/_V.WPG$/_T($M2BQ`02(`X`+!\`"UF#D)MU
  616. M__@@2U*+$!!(@#@`N'P`,&80.WP`,/_V($M2BQ`02(`X`+A\`"IF&"!M__Q4U
  617. MK?_\.U#_\B!+4HL0$$B`.`!@,D)M__)@'#`M__+!_``*T$20?``P.T#_\B!+V
  618. M4HL0$$B`.``P!%)`0>R!&@@P``(``&;4N'P`+F9:($M2BQ`02(`X`+!\`"IF%
  619. M&"!M__Q4K?_\.U#_]"!+4HL0$$B`.`!@,D)M__1@'#`M__3!_``*T$20?``P9
  620. M.T#_]"!+4HL0$$B`.``P!%)`0>R!&@@P``(``&;4.WP``O_PN'P`;&82($M25
  621. MBQ`02(`X`#M\``3_\&`0N'P`:&8*($M2BQ`02(`X`#`$2,!@>#M\``C_[F`6O
  622. M.WP`"O_N8`X[?``0_^Y@!CM\__;_[C\M__!(;?\P/RW_[B\M__Q.NOWD3^\`E
  623. M#"M`_^HP+?_P2,#1K?_\8%H@;?_\6*W__"M0_^HO+?_J3KH"#%A/.T#_\&!*I
  624. M(&W__%2M__PX$$'M_R\K2/_J$(1@*)"\````8V?B4X!GE)"\````"V<`_W19P
  625. M@&>T58!G`/]R5X!G`/]T8,Q![?\PD>W_ZCM(__`P+?_PL&W_]&\&.VW_]/_PV
  626. M2FW_^&=H(&W_Z@P0`"UG"B)M_^H,$0`K9BX,;0`P__9F)E-M__(@;?_J4JW_0
  627. MZA`02(`_`$Z25$^P?/__9@IP_TS?#!!.74YU8!8_+?_V3I)43[!\__]F!'#_O
  628. M8.12;?_Z,"W_\E-M__*P;?_P;MQ";?_N8"`@;?_J4JW_ZA`02(`_`$Z25$^PE
  629. M?/__9@1P_V"P4FW_[B!M_^I*$&<*,"W_[K!M__1MSC`M_^[1;?_Z2FW_^&8HB
  630. M8!@_/``@3I)43[!\__]F!G#_8`#_>%)M__HP+?_R4VW_\K!M__!NVF`6/P1.$
  631. MDE1/L'S__V8&</]@`/]24FW_^F``_0HP+?_Z8`#_0DCG2`!"A$J`:@1$@%)$0
  632. M2H%J!D2!"D0``6$^2D1G`D2`3-\`$DJ`3G5(YT@`0H1*@&H$1(!21$J!:@)$]
  633. M@6$:(`%@V"\!81(@`2(?2H!.=2\!808B'TJ`3G5(YS``2$%*068@2$$V`30`Y
  634. M0D!(0(##(@!(0#("@L,P`4)!2$%,WP`,3G5(028!(@!"04A!2$!"0'0/T(#3U
  635. M@;:!8@22@U)`4<K_\DS?``Q.=2!O``0@"$H89OR1P"`(4X!.=4Y5``!(;(&RC
  636. M/RT`"$ZZ``A<3TY=3G5.50``+P0X+0`(+RT`"C\$3KH`,%Q/N'P`"F8D(&T`!
  637. M"A`H``Q(@`@```=G%#\\__\O+0`*3KH`]EQ/*!].74YU8/A.50``+PHD;0`*L
  638. M(%*QZ@`$91@P+0`(P'P`_S\`+PI.N@#*7$\D7TY=3G4@4E*2$"T`"1"`2(#`(
  639. M?`#_8.A.50``+PI![(&<)$@@2M7\````%B\(81!83T'L@U2UR&7J)%].74YUV
  640. M3E4``$CG""`D;0`(>``@"F8*</],WP003EU.=4HJ``QG4@@J``(`#&<,/SS_G
  641. M_R\*851<3S@`$"H`#4B`/P!.N@3R5$^(0`@J``$`#&<*+RH`"$ZZ`C!83P@JK
  642. M``4`#&<4+RH`$DZZ`L)83R\J`!).N@(46$]"DD*J``1"J@`(0BH`##`$8(Y.Z
  643. M5?_^2.<(("1M``A!^O]$*4B#@@@J``0`#&<*</],WP003EU.=0@J``(`#&<P<
  644. M(!*0J@`(.``_!"\J``@0*@`-2(`_`$ZZ`H!03[!$9Q`(Z@`$``Q"DD*J``1PH
  645. M_V#`#&W__P`,9A`(J@`"``Q"DD*J``1P`&"H2JH`"&8(+PI.N@":6$\,:@`!W
  646. M`!!F*AMM``W__S\\``%(;?__$"H`#4B`/P!.N@(B4$^P?``!9J`P+0`,8`#_V
  647. M:B2J``@P*@`02,#0J@`()4``!`CJ``(`#"!24I(0+0`-$(!(@,!\`/]@`/\^M
  648. M3E4``"\*0>R!G"1(2BH`#&<8U?P````60>R#5+7(90AP`"1?3EU.=6#B0I)"?
  649. MJ@`$0JH`""`*8.I.5?_\+PHD;0`(/SP$`$ZZ`,!43RM`__QF\``$`$"`*`
  650. MT+P````.)4``""1?3EU.=35\!```$`CJ``$`#"5M__P`"!`J``U(@#\`3KH`G
  651. MXE1/2D!G!@`J`(``#&#.3E4``$CG`#`D;(-68!0F4B`J``10@"\`+PI.N@5PZ
  652. M4$\D2R`*9NA"K(-63-\,`$Y=3G5.50``+PI!^O_&*4B#AD*G("T`"%"`+P!.3
  653. MN@464$\D0$J`9@AP`"1?3EU.=22L@U8E;0`(``0I2H-6(`I0@&#F3E4``'``7
  654. M,"T`""\`8;)83TY=3G5.50``2.<`,)?+)&R#5F`.(&T`"%&(L<IG$B9*)%(@?
  655. M"F;N</],WPP`3EU.=2`+9P0FDF`$*5*#5B`J``10@"\`+PI.N@3"4$]P`S
  656. M3E4``"\*,"T`",'\``8D0-7L@VA*;0`(;0XP+0`(L&R#5&P$2I)F#CE\``*#@
  657. M6G#_)%].74YU,"T`",'\``8@;(-H+S`(`$ZZ`JA83TJ`9P1P`6`"<`!@V$Y5L
  658. M```O+0`(3KH"<EA/2H!F#DZZ`GPY0(-:</].74YU<`!@^$Y5``!(YPP@."T`I
  659. M"$ZZ`'`P!,'\``8D0-7L@VA*1&T*N&R#5&P$2I)F$#E\``*#6G#_3-\$,$Y=6
  660. M3G4P*@`$P'P``V8*.7P`!8-:</]@Y'``,"T`#B\`+RT`"B\23KH";D_O``PJW
  661. M`+"\_____V8,3KH!_#E`@UIP_V"X(`5@M$Y5__Q(>!``0J=.N@0P4$\K0/_\-
  662. M"```#&<22FR#<&8(("W__$Y=3G5.N@`&<`!@]$Y5``!(>``$2'H`'DZZ`>`O+
  663. M`$ZZ`@I/[P`,/SP``4ZZ``Q43TY=3G5>0PH`3E4``$JL@X)G!B!L@X).D#\M0
  664. M``A.N@`(5$].74YU3E7__"\$,"T`"$C`*T#__$JL@VAG*'@`8`H_!$ZZ`-!4.
  665. M3U)$N&R#5&WP,"R#5,'\``8O`"\L@VA.N@,,4$]*K(.&9P8@;(.&3I!*K(.*`
  666. M9PHO+(.*3KH!S%A/2JR#CF<*+RR#CDZZ`;Q83TJL@Y)G"B\L@Y).N@&L6$\L9
  667. M>``$""X`!`$I9Q0O#4OZ``I.KO_B*E]@!D*G\U].<TJL@W)F,$JL@WYG*#`L1
  668. M@WQ(P"\`+RR#?DZZ`I)03S`L@WI20$C`Y8`O`"\L@W9.N@)\4$]@#DZZ`F@O<
  669. M+(-R3KH"W%A/("W__"YL@UQ.=2@?3EU.=4Y5``!(YPX@."T`"#`$P?P`!B1`O
  670. MU>R#:$I$;0JX;(-4;`1*DF80.7P``H-:</],WP1P3EU.=3`J``3`?(``9@@OU
  671. M$DZZ``I83T*2<`!@X"(O``0L;(-D3N[_W"(O``0L;(-D3N[_@B(O``0L;(-D?
  672. M3N[_.B(O``0L;(-D3N[_N"QL@V1.[O_*+&R#9$[N_WPB+P`$+&R#9$[N_RA,Y
  673. M[P`&``0L;(-D3N[_K$SO``8`!"QL@V1.[O_B+&R#9$[N_\1,[P`.``0L;(-D*
  674. M3N[_UDSO``X`!"QL@V1.[O^^(B\`!"QL@V1.[O^F3.\`#@`$+&R#9$[N_]!(J
  675. MYP$$3.\@@``,+&R#8$ZN_Y1,WR"`3G4B;P`$+&D`%$[N_^(B;P`$+&R#8$[N2
  676. M_BPB;P`$+&R#8$[N_CY.^@`"(F\`!"QL@V!.[OYB3E4``$CG""!(>/__3KH`H
  677. MT%A/*`"PO/____]F"G``3-\$$$Y=3G5(>0`!``%(>``B3KH`N%!/)$!*@&8,X
  678. M+P1.N@#H6$]P`)6T`"``*%6T`#P`)%7P`!``(0BH`#A5$``]"ITZZ`)98,
  679. M3R5``!!*K0`(9PHO"DZZ`%I83V`*2&H`%$ZZ`,!83R`*8)).50``+PHD;0`(F
  680. M2JH`"F<(+PI.N@#<6$\5?`#_``@E?/____\`%'``$"H`#R\`3KH`;%A/2'@`]
  681. M(B\*3KH`3%!/)%].74YU(F\`!"QL@V!.[OZ>("\`!"QL@V!.[OZV3OH``DSOJ
  682. M``,`!"QL@V!.[O\Z3OH``B)O``0L;(-@3N[^VBQL@V!.[O]\3OH``B)O``0@6
  683. M+P`(+&R#8$[N_RX@+P`$+&R#8$[N_K!.^@`"(&\`!"QL@V!.[OZ,(&\`!""(L
  684. M6)!"J``$(4@`"$YU(&\`!$SO`@$`""(O`!`L;(-@3N[^1"QL@V`B;P`$("\`<
  685. M"$[N_=@B;P`$+&R#8$[N_I@B;P`$+&R#8$[N_H9,[P`#``0L;(-@3N[^SB)OA
  686. M``0L;(-@3N[^)B!O``0L;(-@3N[^@$SO`P``!"QL@[9.[O^@(&\`!"QL@[9.'
  687. M[O^F(&\`!"QL@[9.[O^R``````/L`````0````$```KL`````````_(```/JM
  688. M````U0!:?UH`IH&F```````````````%```$K```!*\```2T```$N0``!+T`S
  689. M``2_```$Q```!,@```3-```$T```!-4```39```$W@``!.$```3D```$Z```-
  690. M!.T```3R```$]@``!/H```3\```%````!04```4)```%#@``!1,```48```%)
  691. M'@``!20```4J```%,```!38```4\```%0@``!4@```5.```%5```!5L```5BN
  692. M```%:0``!7````5W```%?0``!80```6+```%D@````!R``````!R*P````)W9
  693. M`````P%W*P```P)A````"0%A*P``"0)X````!0%X*P``!0(````````P,3(S;
  694. M-#4V-S@Y86)C9&5F````("`@("`@("`@,#`P,#`@("`@("`@("`@("`@("`@L
  695. M(""00$!`0$!`0$!`0$!`0$!`#`P,#`P,#`P,#$!`0$!`0$`)"0D)"0D!`0$!"
  696. M`0$!`0$!`0$!`0$!`0$!`4!`0$!`0`H*"@H*"@("`@("`@("`@("`@("`@("N
  697. M`@("0$!`0"```````````````````0`````!``````````````````````$!J
  698. M`````0`````````````````````!`@````$`````````````````````````%
  699. M`````````````````````````````````````````````````````````````
  700. M`````````````````````````````````````````````````````````````
  701. M`````````````````````````````````````````````````````````````
  702. M`````````````````````````````````````````````````````````````
  703. M`````````````````````````````````````````````````````````````
  704. M`````````````````````````````````````````````````````````````
  705. M`````````````````````````````````````````````````````````````
  706. M`````````````````````````````````````````````````````````````
  707. M%````^P````N`````````!0````8````'````"`````D````*````"P````P!
  708. M````-````#@````\````0````$0```!(````3````%````!4````6````%P`8
  709. M``!@````9````&@```!L````<````'0```!X````?````(````"$````B```\
  710. M`(P```"0````E````)@```"<````H````*0```"H````K````+````"T````@
  711. EN````+P```#`````Q````,@````````#\@```^L````!```#\K``)
  712. ``
  713. end
  714. size 8992
  715. SHAR_EOF
  716. #    End of shell archive
  717. exit 0
  718. -- 
  719. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  720. Have five nice days.
  721.